#include <linux/fs.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/slab.h>

#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/of_graph.h>
#include <linux/platform_device.h>

#define TAG "of_graph"
#define LOG_INF(format, args...)    pr_info(TAG "[%s:%d] " format, __func__, __LINE__, ##args)
#define LOG_ERR(format, args...)    pr_err(TAG "[%s:%d] " format, __func__, __LINE__, ##args)

#define TGA_COMPATIBLE "rockchip,tga"
#define TGB_COMPATIBLE "rockchip,tgb"
#define TGC_COMPATIBLE "rockchip,tgc"



void of_graph_parse(struct device *dev)
{

	struct device_node *port, *endpoint, *endpoint1;
	struct device_node *ep1, *ep2, *ep3;
	struct device_node *dn = dev->of_node;
	struct device_node *tga, *tgb, *tgc, *tmp;

	ep1 = ep2 = ep3 = NULL;  // init it, suppress unused variable
	tga = of_find_compatible_node(NULL, NULL, TGA_COMPATIBLE);
	tgb = of_find_compatible_node(NULL, NULL, TGB_COMPATIBLE);
	tgc = of_find_compatible_node(NULL, NULL, TGC_COMPATIBLE);

	port = of_graph_get_port_by_id(dn, 0);
	if(!port){
		LOG_ERR("of_graph_get_port_by_id fail\n");
		return;
	}
	endpoint = of_get_next_child(port, NULL);
	endpoint1 = of_graph_get_next_endpoint(dn, NULL);
	LOG_INF("endpoint=%p, endpoint1=%p\n", endpoint, endpoint1);

	tmp = of_graph_get_remote_node(tga, 0, 0);
	LOG_INF("of_graph_get_remote_node=%p, of_find_compatible_node=%p\n", tmp, tgb);

	tmp = of_graph_get_remote_node(tgb, 0, 0);
	LOG_INF("of_graph_get_remote_node=%p, of_find_compatible_node=%p\n", tmp, tgc);
}


static int dts_demo_remove(struct platform_device *pdev)
{
	LOG_INF("enter");
	return 0;
}

static int dts_demo_probe(struct platform_device *pdev)
{
	LOG_INF("enter");
	of_graph_parse(&pdev->dev);
	return 0;
}

static const struct of_device_id dts_demo_match[] = {
	{ .compatible = "rockchip,tga",},
	{}
};

static struct platform_driver dts_demo_driver = {
	.probe = dts_demo_probe,
    .remove = dts_demo_remove,
    .driver = {
        .name = TAG,
 //       .module = THIS_MODULE,
        .of_match_table = dts_demo_match,
    },
};

static int __init demo_init(void)
{
	int err = 0;
	LOG_INF("enter");
	//parse_gpio();
	if((err = platform_driver_register(&dts_demo_driver))<0){
		LOG_ERR("platform_driver_register fail, err=%d\n", err);
		return err;
	}
	return 0;
}

static void __exit demo_exit(void)
{
	LOG_INF("enter");
	platform_driver_unregister(&dts_demo_driver);
	return;
}

module_init(demo_init);
module_exit(demo_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("tj<tj_wust@163.com>");